import styled from 'styled-components';
import { throttle } from 'lodash';
import { HomeResponse } from '../../service/interface'
import Icon from '../../component/Icon';
import AnimatedTextComponent from '../../component/AnimationText';
import AnimationCycle from '../../component/AnimationCycle';
import React, { useEffect, useMemo, useRef, useState } from 'react';
import Action from './Action';
import Power from './Power';
import { startDig } from '../../service'
import Message from '../../component/Message';
import { chargingTime, saveChargingTime } from '../../utils/user';
import { useTranslation } from 'react-i18next';
import { CHARGING_TIME } from '../../constants';
import { fract } from '../../utils/number'
import gtag from '../../google/analytics';
import { GtagEvent } from '../../google/analytics/Event';
import Loading from '../../component/Loading';
import { useNavigate } from 'react-router-dom';
import { Router } from '../../router';
import { SwitchConfigKeys } from '../../utils/switch';
import useSwitch from '../../hook/switch';
import Trade from './Trade';
import Prize from './prize';


const CYCLE_RADIUS = 90
const BUTTON_SIZE = 40
const SCREEN_WIDTH = 375
const IMAGE_TOP = 40
const ANGLE_END = 360
const RANK_TOP = 25

const Container = styled.div`
    position: relative;
`

const IconBox = styled.div<{ $height?: number }>`
    margin-top: -${IMAGE_TOP + RANK_TOP}px;
    box-sizing: border-box;
    position: relative;
    height: ${({ $height }) => $height ? `${$height}px` : undefined};
`

const Rank = styled(Icon)`
    width: 6.75rem;
`

const Ton = styled(Icon)`
    width: 100%;
    aspect-ratio: 1;
`

const TonBox = styled.div`
    width: 6.0938rem;
    aspect-ratio: 1;
    position: absolute;
    right: 1.125rem;
    top: -${RANK_TOP + 20}px;
`

const TradeBox = styled(Trade)`
    position: absolute;
    right: 1.125rem;
    transform: translateY(-100%);
`

const PrizeBox = styled(Prize)`
    position: absolute;
    top: -${RANK_TOP}px;
    /* transform: translateY(-50%); */
    left: 1.125rem;
`

const TopExtra = styled.div`
    position: relative;
    margin-top: ${RANK_TOP}px;
    z-index: 2;
    width: 100%;
    display: flex;
    justify-content: center;
`

const BottomExtra = styled.div<{ $bottom?: string }>`
    width: 100%;
    position: absolute;
    top: ${({ $bottom }) => `${$bottom || 0}`};
    z-index: 2;
    .inner {
        position: relative;
    }
`

const Cycle = styled(AnimationCycle)`
    position: absolute !important;
    top: 0;
`

const Increase = styled.div<{ $offsetY?: number }>`
    font-weight: 400;
    font-size: 21px;
    color: #FEA327;
    position: absolute;
    top: ${({ $offsetY }) => `calc(50% + ${$offsetY}px)`};
    left: 50%;
    transform: translate(-50%, -50%);
    
`

const ActionBox = styled(Action) <{ $marginTop?: number }>`
    position: relative;
    padding-bottom: .625rem;
    box-sizing: border-box;
    margin-top: ${({ $marginTop }) => `${$marginTop || 0}px`};
`

const PowerBox = styled(Power) <{ $marginTop?: number }>`
    margin-top: ${({ $marginTop }) => `${$marginTop || 0}px`};
    position: relative;
    z-index: 1;
`

interface Props {
    isStart?: boolean;
    onStart: (start: boolean) => void;
    data?: HomeResponse
    leftCycleCount?: number;
    stopTime: number;
}

const Content: React.FC<Props> = ({ isStart, onStart, data, stopTime, leftCycleCount = 0 }) => {
    const { t } = useTranslation();
    const navigate = useNavigate()
    const [radius, setRadius] = useState(CYCLE_RADIUS);
    const [actionTop, setActionTop] = useState<number>(0);
    const [bottomExtraTop, setBottomExtraTop] = useState<number>(0);
    const [cycleCount, setCycleCount] = useState(leftCycleCount);
    const [decimalCycle, setDecimalCycle] = useState(1);
    const [animation, setAnimation] = useState(false);
    const [angle, setAngle] = useState({ start: 0, end: ANGLE_END })
    const [repeat, setRepeat] = useState(true);
    const [loading, setLoading] = useState(false);

    const ref = useRef<HTMLDivElement>(null);
    const cycleSecond = useMemo(() => Number(data?.detector.speedRate || 0) * decimalCycle, [data?.detector.speedRate, decimalCycle])
    const start = useMemo(() => isStart, [isStart])
    const increase = useMemo(() => (data?.detector.realDetPower || 0), [data?.detector.realDetPower])
    const increasStr = useMemo(() => `+ ${Number(data?.detector.detPower || 0).toFixed(2)}${Number(data?.detector.detTonAmplify) > 1 ? ` X${data?.detector.detTonAmplify}` : ''}`, [data?.detector.detPower, data?.detector.detTonAmplify])
    const textValue = useMemo(() => ({ start: decimalCycle === 1 ? 0 : (1 - decimalCycle) * increase, end: increase }), [increase, decimalCycle])

    const [config] = useSwitch()
    const showTon = useMemo(() => config.boolForKey(SwitchConfigKeys.TonWalletSwitch, false), [config])

    useEffect(() => {
        const r = CYCLE_RADIUS * (ref.current?.clientWidth || SCREEN_WIDTH) / SCREEN_WIDTH;
        setActionTop(-((ref.current?.clientWidth || SCREEN_WIDTH) / 2 - r - BUTTON_SIZE / 2))
        setBottomExtraTop((ref.current?.clientWidth || 0) / 2 + r - BUTTON_SIZE)
        setRadius(r)
    }, [ref]);

    const distance = useMemo(() => radius, [radius])

    useEffect(() => {
        const decimal = fract(leftCycleCount)
        if (decimal >= 0.01) {
            setDecimalCycle(decimal)
            setRepeat(false)
            setAngle({
                start: (1 - decimal) * ANGLE_END,
                end: ANGLE_END
            })
        }
        setCycleCount(leftCycleCount < 0 ? 0 : Math.ceil(leftCycleCount))
    }, [leftCycleCount])

    useEffect(() => {
        if (isStart) {
            return
        }

        const time = chargingTime();
        if (!time) {
            return;
        }

        const total = Number(data?.detector.cycleLength || 0);
        if (!total) {
            return
        }

        const current = Math.floor((CHARGING_TIME - time) / CHARGING_TIME * total)
        const num = Math.floor(total / CHARGING_TIME)
        setCycleCount(current);
        const timer = setInterval(() => {
            setCycleCount(pre => {
                const value = pre + num;
                if (value >= total) {
                    clearInterval(timer)
                    return total
                }
                return value;
            })
        }, 1000)

        return () => clearInterval(timer)

    }, [isStart, data])

    const onClick = async () => {
        if (start) {
            return;
        }

        const duraiton = chargingTime()
        if (duraiton) {
            Message.info(t('home.charging'));
            return;
        }

        setLoading(true)
        const result = await startDig();
        setLoading(false)
        if (!result.success) {
            Message.error(result.message)
            return;
        }
        gtag.event(GtagEvent.Start)
        onStart(true)
    }

    const onRankClick = () => {
        gtag.event(GtagEvent.Leaderboard)
        navigate(Router.Ranking)
    }

    const onTonClick = () => {
        gtag.event(GtagEvent.Earn)
        navigate(Router.Ton)
    }

    const onAnimationIteration = () => {
        if (decimalCycle > 0 && decimalCycle < 1) {
            setDecimalCycle(1)
            setRepeat(true)
            setAngle({ start: 0, end: ANGLE_END })
        }
        setCycleCount(pre => {
            const value = pre - 1;
            if (value <= 0) {
                onStart(false)
                // neet to charging
                saveChargingTime();
                return 0
            }
            return value
        })

        // second cycle start animation
        if (!animation) {
            setAnimation(true)
        }
    }

    return <Container>
        <TopExtra>
            <Rank
                name='ranking'
                onClick={onRankClick}
            />
            <PrizeBox />
            {showTon && <TonBox onClick={onTonClick}>
                <Ton
                    name='home_ton'
                    type='gif'
                />
            </TonBox>}
        </TopExtra>
        <BottomExtra
            $bottom={`${bottomExtraTop}px`}
        >
            <div className='inner'>
                <TradeBox />
            </div>
        </BottomExtra>
        <IconBox
            ref={ref}
            $height={ref.current?.clientWidth}
        >
            <Icon
                name='home_earth'
                width="100%"
            />
            <Cycle
                onAnimationIteration={onAnimationIteration}
                radius={radius}
                isAnimating={Boolean(start)}
                second={cycleSecond}
                angle={angle}
                repeat={repeat}
                position='bottom'
                dot={{
                    size: BUTTON_SIZE,
                    element: <Icon
                        onClick={throttle(onClick)}
                        name={!data?.detector.detTonAmplifyUrl ? 'accelerate_detector' : undefined}
                        src={data?.detector.detTonAmplifyUrl}
                        width={`${BUTTON_SIZE}px`}
                    />
                }}
            />
            <Increase $offsetY={radius - BUTTON_SIZE}>
                {start && animation && <AnimatedTextComponent
                    duration={2}
                    displayDuration={0.5}
                    loopDuration={cycleSecond}
                    gradient={true}
                    distance={distance}
                    element={increasStr}
                />}
            </Increase>
        </IconBox>
        {!start && <ActionBox
            $marginTop={actionTop}
            onClick={throttle(onClick)}
        />}
        <PowerBox
            stopTime={stopTime}
            duration={cycleSecond * 1000}
            $marginTop={start ? actionTop : 0}
            start={start}
            total={Number(data?.detector.cycleLength || 0)}
            current={cycleCount}
            count={textValue}
        />
        <Loading
            show={loading}
        />
    </Container>
}

export default Content